home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / DVIPS_55 / dvips / src / c / pprescan < prev    next >
Text File  |  1994-05-06  |  9KB  |  269 lines

  1. /*
  2.  *   This is the main routine for the first (prescanning) pass.
  3.  */
  4. #include "dvips.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are all the external routines it calls:
  7.  */
  8. extern shalfword dvibyte() ;
  9. extern halfword twobytes() ;
  10. extern integer threebytes() ;
  11. extern integer signedquad() ;
  12. extern shalfword signedbyte() ;
  13. extern shalfword signedpair() ;
  14. extern integer signedtrio() ;
  15. extern void skipover() ;
  16. extern void fontdef() ;
  17. extern void predospecial() ;
  18. extern int residentfont() ;
  19. extern Boolean virtualfont() ;
  20. extern void error() ;
  21. extern long getlong() ;
  22. extern int skipnop() ;
  23. extern void skippage() ;
  24. extern void readpreamble() ;
  25. extern void bopcolor() ;
  26. extern int InPageList() ;
  27. /*
  28.  *   These are the globals it accesses.
  29.  */
  30. #ifdef DEBUG
  31. extern integer debug_flag;
  32. #endif  /* DEBUG */
  33. extern fontdesctype *fonthead ;
  34. extern integer firstpage, lastpage ;
  35. extern integer firstseq, lastseq ;
  36. extern Boolean notfirst, notlast ;
  37. extern Boolean evenpages, oddpages, pagelist ;
  38. extern integer maxpages ;
  39. extern Boolean abspage ;
  40. extern FILE *dvifile ;
  41. extern fontdesctype *curfnt ;
  42. extern fontdesctype *baseFonts[] ;
  43. extern fontmaptype *ffont ;
  44. extern quarterword *curpos, *curlim ;
  45. extern integer pagenum ;
  46. extern char errbuf[] ;
  47. extern frametype frames[] ;
  48. /*
  49.  *  We declare this to tell everyone we are prescanning early.
  50.  */
  51. Boolean pprescan ;
  52. /*
  53.  * When a font is selected during the pre-prescan, this routine makes sure
  54.  * that the tfm or vf (but not pk) file is loaded.
  55.  */
  56. static void
  57. ppreselectfont(f)
  58. fontdesctype *f ;
  59. {
  60.    int i ;
  61.  
  62.    curfnt = f ;
  63.    if (curfnt->loaded == 0) {
  64.       if (!residentfont(curfnt))
  65.          if (!virtualfont(curfnt)) {
  66.             for (i=0; i<256; i++)
  67.                curfnt->chardesc[i].flags = 0 ;
  68.             curfnt->loaded = 3 ; /* we're scanning for sizes */
  69.          }
  70.    }
  71. }
  72. /*
  73.  *   Now our scanpage routine.
  74.  */
  75. static void
  76. pscanpage()
  77. {
  78.    register shalfword cmd ;
  79.    register chardesctype *cd ;
  80.    register fontmaptype *cfnt = 0 ;
  81.    integer fnt ;
  82.    register frametype *frp = frames ;
  83.  
  84. #ifdef DEBUG
  85.    if (dd(D_PAGE))
  86. #ifdef SHORTINT
  87.    (void)fprintf(stderr,"PPrescanning page %ld\n", pagenum) ;
  88. #else   /* ~SHORTINT */
  89.    (void)fprintf(stderr,"PPrescanning page %d\n", pagenum) ;
  90. #endif  /* ~SHORTINT */
  91. #endif  /* DEBUG */
  92.    curfnt = NULL ;
  93.    curpos = NULL ;
  94.    bopcolor(0) ;
  95.    while (1) {
  96.       switch (cmd=dvibyte()) {
  97. case 129: case 130: case 131: case 134: case 135: case 136: case 139:
  98. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  99. case 254: case 255: /* unimplemented or illegal commands */
  100.          (void)sprintf(errbuf,
  101.             "! DVI file contains unexpected command (%d)",cmd) ;
  102.          error(errbuf) ;
  103. case 132: case 137: /* eight-byte commands setrule, putrule */
  104.          (void)dvibyte() ;
  105.          (void)dvibyte() ;
  106.          (void)dvibyte() ;
  107.          (void)dvibyte() ;
  108. case 146: case 151: case 156: case 160: case 165: case 170:
  109.    /* four-byte commands right4, w4, x4, down4, y4, z4 */
  110.          (void)dvibyte() ;
  111. case 145: case 150: case 155: case 159: case 164: case 169:
  112.    /* three-byte commands right3, w3, x3, down3, y3, z3 */
  113.          (void)dvibyte() ;
  114. case 144: case 149: case 154: case 158: case 163: case 168:
  115.    /* two-byte commands right2, w2, x2, down2, y2, z2 */
  116.          (void)dvibyte() ;
  117. case 143: case 148: case 153: case 157: case 162: case 167:
  118.    /* one-byte commands right1, w1, x1, down1, y1, z1 */
  119.          (void)dvibyte() ;
  120. case 147: case 152: case 161: case 166: /* w0, x0, y0, z0 */
  121. case 138: case 141: case 142: /* nop, push, pop */
  122.          break ;
  123. case 133: case 128: cmd = dvibyte() ; /* set1 commands drops through */
  124. default:    /* these are commands 0 (setchar0) thru 127 (setchar 127) */
  125.          if (curfnt==NULL)
  126.             error("! Bad DVI file: no font selected") ;
  127.          if (curfnt->loaded == 2) { /* scanning a virtual font character */
  128.             frp->curp = curpos ;
  129.             frp->curl = curlim ;
  130.             frp->ff = ffont ;
  131.             frp->curf = curfnt ;
  132.             if (++frp == &frames[MAXFRAME] )
  133.                error("! virtual recursion stack overflow") ;
  134.             cd = curfnt->chardesc + cmd ;
  135.             if (cd->packptr == 0)
  136.     error("! a non-existent virtual char is being used; check vf/tfm files") ;
  137.             curpos = cd->packptr + 2 ;
  138.             curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  139.             ffont = curfnt->localfonts ;
  140.             if (ffont==NULL)
  141.                curfnt = NULL ;
  142.             else
  143.                ppreselectfont(ffont->desc) ;
  144.          } else if (curfnt->loaded == 3)
  145.             curfnt->chardesc[cmd].flags = EXISTS ;
  146.          break ;
  147. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  148. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  149. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  150. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  151. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  152. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  153. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  154. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  155. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  156. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  157.          if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  158.          else {
  159.             fnt = dvibyte() ; /* fnt1 */
  160.             while (cmd-- > 235)
  161.                fnt = (fnt << 8) + dvibyte() ;
  162.          }
  163.          if (curpos || fnt > 255) {
  164.             for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  165.                if (cfnt->fontnum == fnt) goto fontfound ;
  166.          } else
  167.             if (0 != (curfnt = baseFonts[fnt]))
  168.                goto fontfound2 ;
  169.             error("! no font selected") ;
  170. fontfound:  curfnt = cfnt->desc ;
  171. fontfound2: ppreselectfont(curfnt) ;
  172.             break ;
  173. case 239: predospecial((integer)dvibyte(), 1) ; break ; /* xxx1 */
  174. case 240: predospecial((integer)twobytes(), 1) ; break ; /* xxx2 */
  175. case 241: predospecial(threebytes(), 1) ; break ; /* xxx3 */
  176. case 242: predospecial(signedquad(), 1) ; break ; /* xxx4 */
  177. case 243: case 244: case 245: case 246: fontdef(cmd-242) ; break ; /* fntdef1 */
  178. case 140: /* eop or end of virtual char */
  179.          if (curpos) {
  180.             --frp ;
  181.             curfnt = frp->curf ;
  182.             ffont = frp->ff ;
  183.             curlim = frp->curl ;
  184.             curpos = frp->curp ;
  185.             break ;
  186.          }
  187.          return ;
  188.       }
  189.    }
  190. }
  191. /*
  192.  *   Finally, here's our main pprescan routine.
  193.  */
  194. static integer firstmatch = -1, lastmatch = -1 ;
  195. void
  196. pprescanpages()
  197. {
  198.    register int cmd ;
  199.    integer lmaxpages = maxpages ;
  200.    integer mpagenum ;
  201.    integer pageseq = 0 ;
  202.    int ntfirst = notfirst ;
  203.  
  204.    pprescan = 1 ;
  205.    readpreamble() ;
  206. /*
  207.  *   Now we look for the first page to process.  If we get to the end of
  208.  *   the file before the page, we complain (fatally).
  209.  *   Incidentally, we don't use the DVI file's bop backpointer to skip
  210.  *   over pages at high speed, because we want to look to for special
  211.  *   header that might be in skipped pages.
  212.  */
  213.    while (1) {
  214.       cmd = skipnop() ;
  215.       if (cmd==248)
  216.          error("! End of document before first specified page") ;
  217.       if (cmd!=139)
  218.          error("! Bad DVI file: expected bop") ;
  219.       pagenum = signedquad() ;
  220.       pageseq++ ;
  221.       mpagenum = abspage ? pageseq : pagenum ;
  222.       if (mpagenum == firstpage && ntfirst)
  223.          firstmatch++ ;
  224.       if (mpagenum == lastpage && notlast)
  225.          lastmatch++ ;
  226.       if (ntfirst && mpagenum == firstpage && firstmatch == firstseq)
  227.          ntfirst = 0 ;
  228.       if (ntfirst ||
  229.       ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
  230.        (pagelist && !InPageList(pagenum)))) {
  231.          skipover(40) ;
  232.          skippage() ;
  233.       } else {
  234.          if (notlast && mpagenum == lastpage)
  235.             lastmatch-- ;
  236.          break ;
  237.       }
  238.    }
  239. /*
  240.  *   Here we scan for each of the sections.  First we initialize some of
  241.  *   the variables we need.  We don't have to be as smart as before in
  242.  *   skipping pages.
  243.  */
  244.    skipover(40) ;
  245.    while (lmaxpages > 0) {
  246.       if (!(evenpages && (pagenum & 1)) &&
  247.          !(oddpages && (pagenum & 1)==0) &&
  248.          !(pagelist && !InPageList(pagenum))) {
  249.          pscanpage() ;
  250.          lmaxpages-- ;
  251.       } else
  252.          skippage() ;
  253.       mpagenum = abspage ? pageseq : pagenum ;
  254.       if (mpagenum == lastpage && notlast)
  255.          lastmatch++ ;
  256.       if (notlast && mpagenum == lastpage && lastmatch == lastseq)
  257.          lmaxpages = -1 ; /* we are done after this page. */
  258.       cmd=skipnop() ;
  259.       if (cmd==248) break ;
  260.       if (cmd!=139)
  261.          error("! Bad DVI file: expected bop") ;
  262.       pagenum = signedquad() ;
  263.       skipover(40) ;
  264.       pageseq++ ;
  265.    }
  266.    fseek(dvifile, 0L, 0) ;
  267.    pprescan = 0 ;
  268. }
  269.